function isValueNumber(value){
    return (/(^-?[0-9]+.\{1}\d+$)|(^-?[1-9]*$)|(^-?0{1}$)/).test(value+'');
}

Vue.component('input-number',{
    template:'\
    <div class="input-number">\
        <input type="text" :value="currentValue" @change="handleChange" >\
        <button @click="handleDown" :disabled="currentValue <= min">-</button>\
        <button @click="handleUp" :disabled="currentValue >= max">+</button>\
    </div>',
    props:{
        max: {
            type: Number,
            default: Infinity
        },
        min: {
            type: Number,
            default: -Infinity
        },
        value: {
            type: Number,
            default: 0
        }
    },
    data: function(){
        return {
            currentValue: this.value
        };
    },
    methods: {
        handleDown: function(){
            if(this.currentValue <= this.min) return;
            this.currentValue--;
        },
        handleUp: function(){
            if(this.currentValue >= this.max) return;
            this.currentValue++;
        },
        handleChange: function(event){
            var val = event.target.value.trim();

            if(isValueNumber(val)){
                val = Number(val);

                if(val > this.max){
                    this.currentValue = this.max;
                }else if(val < this.min){
                    this.currentValue = this.min;
                }else{
                    this.currentValue = val;
                }
            }else{
                event.target.value = this.currentValue;
            }
        },
        updateValue: function(val){
            if(val > this.max) this.currentValue = this.max;
            else if(val < this.min) this.currentValue = this.min;
            else this.currentValue = this.value;
        }
    },
    watch: {
        value: function(val, oldVal){
            console.log('[value change] ' + oldVal + "  ->  " + val);
            this.updateValue(val);
        },
        currentValue: function(val, oldVal){
            console.log('[currentValue change] ' + oldVal + "  ->  " + val);
            this.$emit('input', val);
        }
    },
    mounted: function(){
        this.updateValue(this.value);
    }
});